/**
 * 
 */
package br.ufal.ic.sd.project.server.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Properties;
import java.util.Set;

import br.ufal.ic.sd.project.server.exception.ServerException;
import br.ufal.ic.sd.project.server.helper.Helper;
import br.ufal.ic.sd.project.server.util.Constants;

/**
 * @author keven andrade
 *
 */
public class Replicator {
    
    private String strFileName;
    private String strFileContent;
    private File logFile;
    
    private Channel objChannel;
    
    public Replicator(String strServerRepository, String strFileName) {
	
	this.strFileName = strFileName;
	
	File file = new File(strServerRepository+this.strFileName);
	
	FileReader fileReader;
	BufferedReader bufferReader; 
	
	try {
	    
	    //create the file reader objets
	    fileReader = new FileReader(file);
	    bufferReader = new BufferedReader(fileReader); 
	    
	    String strLine = null;
	    
	    while ((strLine = bufferReader.readLine()) != null) { 
                this.strFileContent += strLine + "\n"; 
            }
	    
	    //close the file reader objects
	    bufferReader.close();  
	    fileReader.close();
	    
	    
        } catch (IOException e) {
    	e.printStackTrace();
        } 
    }

    /**
     * @return the objChannel
     */
    public Channel getObjChannel() {
        return objChannel;
    }

    /**
     * @param objChannel the objChannel to set
     */
    public void setObjChannel(Channel objChannel) {
        this.objChannel = objChannel;
    }

    /**
     * @return the strFileName
     */
    public String getStrFileName() {
        return strFileName;
    }

    /**
     * @param strFileName the strFileName to set
     */
    public void setStrFileName(String strFileName) {
        this.strFileName = strFileName;
    }

    /**
     * @return the strFileContent
     */
    public String getStrFileContent() {
        return strFileContent;
    }

    /**
     * @param strFileContent the strFileContent to set
     */
    public void setStrFileContent(String strFileContent) {
        this.strFileContent = strFileContent;
    }

    /**
     * @return the logFile
     */
    public File getLogFile() {
        return logFile;
    }

    /**
     * @param logFile the logFile to set
     */
    public void setLogFile(File logFile) {
        this.logFile = logFile;
    }

    public void reply(){
	
	Properties objProperties = null;
	
	try {
	    objProperties = Helper.loadFile(Constants.REPLICATION_PROPERTIES);
	} catch (ServerException e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	}
	
	Set<String> serversPort = objProperties.stringPropertyNames();
	
	for(String port: serversPort){
	    
	    this.createChannel(objProperties.getProperty(port), Integer.parseInt(port));
	    this.connect();
	    
	    try {
	            this.objChannel.write("REPLICATION");
		    this.objChannel.getObjOutputStreamOut().flush();
		    this.objChannel.write(this.strFileName);
		    this.objChannel.getObjOutputStreamOut().flush();
		    this.objChannel.write(this.strFileContent);
//		    this.objChannel.write("DONE");
//		    this.objChannel.getObjOutputStreamOut().flush();
//		    System.out.println(this.objChannel.getObjInputStreamIn().read());
		    
	    } catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	   
	    this.closeConnection();
	}
	
        
	
    }

    private void createChannel(String strIP, int intPort) {
	this.objChannel = new Channel(strIP, intPort);
    }
    
    public void connect(){
	this.objChannel.connect();
    }

    private void closeConnection() {
	
	this.objChannel.close();
    }
}
